home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / vmake / symbol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  8.0 KB  |  274 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. #ifdef MAIN
  7. #include <stdio.h>
  8. #include <string.h>
  9. #define free_mem(a,b) free(a)
  10. #define get_mem(a)    malloc(a)
  11. #define Prototype
  12. #else
  13. #include "vmake.h"
  14. #endif
  15. struct SYMBOL {
  16.   struct SYMBOL *next;
  17.   char *val;
  18.   short curlen;
  19.   short allotlen;
  20.   char name[1];
  21. };
  22. Prototype void Sym_Clear(void);
  23. Prototype void *Sym_Next(void *cursym, char **name, char **val);
  24. Prototype char *Sym_Lookup(char *name);
  25. Prototype int Sym_Set(char *name, char *val1, char *val2);
  26.  
  27. struct SYMBOL *base, *last; /* Root and end of all symbol entries   */
  28. struct SYMBOL *symcache;    /* Cached entry of last symbol found    */
  29. /***********************************************************************************
  30.  * Procedure: Sym_Clear
  31.  * Synopsis:  rc = set_option(object, optstr)
  32.  * Purpose:   Clear out all of the symbols.  This leaves private ones untouched
  33.  ***********************************************************************************/
  34. void Sym_Clear()
  35. {
  36.    struct SYMBOL *sym, *symnext, *savesym;
  37.  
  38.    savesym = NULL;
  39.  
  40.    sym = base;
  41.    base = last = NULL;
  42.  
  43.    while(sym != NULL)
  44.    {
  45.       symnext = sym->next;
  46.       if (sym->name[0] == '_')
  47.       {
  48.          if (base == NULL)
  49.          {
  50.             base = last = sym;
  51.          }
  52.          else
  53.          {
  54.             last = last->next = sym;
  55.          }
  56.          sym->next = NULL;
  57.       }
  58.       else
  59.       {
  60.          free_mem(sym->val, sym->allotlen);
  61.          free_mem(sym, sizeof(struct SYMBOL) + strlen(sym->name));
  62.       }
  63.       sym = symnext;
  64.    }
  65.    symcache = NULL;
  66. }
  67.  
  68. /***********************************************************************************
  69.  * Procedure: Sym_Next
  70.  * Synopsis:  place = Sym_Next(place, &name, &val);
  71.  * Purpose:   Return the next public symbol in a string
  72.  ***********************************************************************************/
  73. void *Sym_Next(void *cursym,
  74.                char **name,
  75.                char **val)
  76. {
  77.    struct SYMBOL *sym;
  78.    sym = (struct SYMBOL *)cursym;
  79.  
  80.    if (sym == NULL) sym = base;
  81.    else sym = sym->next;
  82.  
  83.    while (sym && (sym->name[0] == '_'))
  84.    {
  85.       sym = sym->next;
  86.    }
  87.  
  88.    *name = "ILLEGAL";
  89.    *val  = "ILLEGAL";
  90.    if (sym != NULL)
  91.    {
  92.       *name = sym->name;
  93.       *val  = sym->val;
  94.    }
  95.    return(sym);
  96. }
  97.  
  98. /***********************************************************************************
  99.  * Procedure: findsymbol
  100.  * Synopsis:  SYMBOL = findsymbol(name);
  101.  * Purpose:   Find the symbol entry for a given name
  102.  ***********************************************************************************/
  103. static struct SYMBOL *findsymbol(char *name)
  104. {
  105.    struct SYMBOL *sym;
  106.    /* See if they are asking for the one we hit last time */
  107.    if (symcache && !strcmp(symcache->name, name)) return(symcache);
  108.    /* Not the same one, do a sequential search on the list.  We can do this     */
  109.    /* Because we know that the number of entries that are generally stored      */
  110.    /* is quite small.  If we change this, this routine would have to be updated */
  111.    for(sym = base; sym != NULL; sym = sym->next)
  112.    {
  113.       if (!strcmp(sym->name, name))
  114.       {
  115.          symcache = sym;      /* Remember it for the cache */
  116.          break;
  117.       }
  118.    }
  119.    return(sym);
  120. }
  121.  
  122. /***********************************************************************************
  123.  * Procedure: Sym_Lookup
  124.  * Synopsis:  val = Sym_Lookup(name)
  125.  * Purpose:   Find the substitution value for a string
  126.  *            If the symbol is not found, a null string is returned.
  127.  *            Originally this returned NULL, but everyone that wants to use it was
  128.  *            checking for this case and then setting the string to "" anyway.
  129.  *            We can create a new routine if this were desired.
  130.  ***********************************************************************************/
  131. char *Sym_Lookup(char *name)
  132. {
  133.    struct SYMBOL *sym;
  134.  
  135.    sym = findsymbol(name);
  136.    if (sym) return(sym->val);
  137.    return("");
  138. }
  139.  
  140. /***********************************************************************************
  141.  * Procedure: Sym_Set
  142.  * Synopsis:  rc = Sym_Set(name, val1, val2)
  143.  * Purpose:   Set a symbol to the concatenation of two values
  144.  ***********************************************************************************/
  145. int Sym_Set(char *name, char *val1, char *val2)
  146. {
  147.    struct SYMBOL *sym;
  148.    int len2, len, len1;
  149.    char *newval;
  150.  
  151.    sym = findsymbol(name);
  152.    if (sym == NULL)
  153.    {
  154.       /* There is a first time for everything, create an empty structure */
  155.       sym = get_mem(sizeof(struct SYMBOL)+strlen(name));
  156.       if (sym == NULL) return(1);
  157.       strcpy(sym->name, name);
  158.       sym->curlen = sym->allotlen = 0;
  159.       sym->val = "";
  160.       sym->next = NULL;
  161.       if (last)
  162.          last->next = sym;
  163.       else
  164.          base = sym;
  165.       last = sym;
  166.    }
  167.  
  168.    /* If they pass NULL as the first parameter, we are doing a concat */
  169.    if (val1 == NULL) val1 = sym->val;
  170.  
  171.    /* We have a valid symbol, see if we can tack on to the end of it */
  172.    /* This one special case will occur when we do concenation to the */
  173.    /* end of a string                                                */
  174.    if (val2 == NULL) val2 = "";
  175.    len2 = strlen(val2);
  176.    if ((val1 == sym->val) && ((sym->curlen + len2) < sym->allotlen))
  177.    {
  178.       /* It is just a tackon case  */
  179. #ifdef MAIN
  180.       printf("Tackon: %d to %d allot=%d\n", len2, sym->curlen, sym->allotlen);
  181. #endif
  182.       strcpy(sym->val+sym->curlen, val2);
  183.       sym->curlen += len2;
  184.       return(0);
  185.    }
  186.  
  187.    /* No, we need to allocate a new area and copy from the two strings into  */
  188.    /* That location.  Note that we can not free the original area because it */
  189.    /* is possible that one of the strings point to it.                       */
  190.    len1 = strlen(val1);
  191.    len = (len1 + len2 + 64) & ~63;
  192. #ifdef MAIN
  193.    printf("Allocate %d for %d + %d\n", len, len1, len2);
  194. #endif
  195.    newval = get_mem(len);
  196.    if (newval == NULL) return(1);
  197.    strcpy(newval, val1);
  198.    strcpy(newval+len1, val2);
  199.    if (sym->allotlen) free_mem(sym->val, sym->allotlen);
  200.    sym->val = newval;
  201.    sym->allotlen = len;
  202.    sym->curlen = len1+len2;
  203.    return(0);
  204. }
  205. /***********************************************************************************
  206.  * Procedure: set_option
  207.  * Synopsis:  rc = set_option(object, optstr)
  208.  * Purpose:   Set an option based on a option string
  209.  ***********************************************************************************/
  210. #ifdef MAIN
  211. void main()
  212. {
  213.    char buf[100];
  214.    char *p;
  215.    void *place;
  216.    char *name, *val;
  217.    int rc;
  218.  
  219.    while((printf(">"), fflush(stdout), gets(buf)) != NULL)
  220.    {
  221.       name = buf+1;
  222.       switch(buf[0])
  223.       {
  224.          case 'd':
  225.             place = NULL;
  226.             while(place = Sym_Next(place, &name, &val))
  227.                printf("%s= %s\n", name, val);
  228.             break;
  229.          case 'p':
  230.             val = Sym_Lookup(name);
  231.             if (val)
  232.                printf("%s= %s\n", name, val);
  233.             else
  234.                printf("%s not found\n", name);
  235.             break;
  236.          case 'c':
  237.             Sym_Clear();
  238.             printf("Cleared\n");
  239.             break;
  240.          case 'a':
  241.          case 's':
  242.             p = name+1;
  243.             while(*p && *p != ' ') p++;
  244.             *p = 0;
  245.             val = p+1;
  246.             if (buf[0] == 'a')
  247.             {
  248.                p = Sym_Lookup(name);
  249.                printf("Setting '%s' to '%s%s'\n", name, p, val);
  250.                rc = Sym_Set(name, NULL, val);
  251.             }
  252.             else
  253.             {
  254.                printf("Setting '%s' to '%s'\n", name, val);
  255.                rc = Sym_Set(name, val, NULL);
  256.             }
  257.             if (rc) printf("Sym_Set failed\n");
  258.             break;
  259.          case 'q':
  260.             Sym_Clear();
  261.             return;
  262.          default:
  263.             printf("Unknown command: %s\n", buf);
  264.             printf("d         - Dump all symbols\n");
  265.             printf("p sym     - Print value of sym\n");
  266.             printf("c         - Clear all symbold\n");
  267.             printf("a sym val - Append val to sym\n");
  268.             printf("s sym val - Set sym to val\n");
  269.             break;
  270.       }
  271.    }
  272. }
  273. #endif
  274.